package com.jwsoft.manager.core.gateway.controller;

import com.bifang.assistant.common.constants.Validators;
import com.bifang.assistant.common.vo.BaseVO;
import com.bifang.engine.assistant.core.domain.AppResponse;
import com.bifang.engine.protect.core.annotation.Idempotent;
import com.bifang.engine.protect.core.annotation.NoSignCrypto;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.constant.EduCache;
import com.jwsoft.manager.common.vo.eduAddress.*;
import com.jwsoft.manager.core.integration.EduAddressIntegration;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * 地址表网关
 *
 * @author wangtao
 * @since 2022-11-24
 */
@Slf4j
@RestController
@RequestMapping(value = "/doc/api")
@Tag(name = "地址表", description = "地址表")
public class EduAddressController {

    @Autowired
    private EduAddressIntegration eduAddressIntegration;
    @Autowired
    private RedissonClient redissonClient;

    @Operation(summary = "地址表分页查询", description = "地址表分页查询")
    @PostMapping(value = "/eduaddress0001", produces = "application/json;charset=UTF-8")
    public AppResponse<PageInfo<EduAddressVO>> getList(@RequestBody @Validated EduAddressQueryVO vo) {
        return AppResponse.successData(eduAddressIntegration.getList(vo));
    }

    @Operation(summary = "地址表根据主键查询详情", description = "地址表根据主键查询详情")
    @PostMapping(value = "/eduaddress0002", produces = "application/json;charset=UTF-8")
    public AppResponse<EduAddressVO> getById(@RequestBody @Validated EduAddressKeyVO vo) {
        return AppResponse.successData(eduAddressIntegration.getById(vo));
    }

    @Idempotent(expire="PT2S") //2秒内防重复提交
    @Operation(summary = "地址表新增",description = "地址表新增")
    @PostMapping(value = "/eduaddress0004", produces = "application/json;charset=UTF-8")
    public AppResponse<EduAddressVO> add(@RequestBody @Validated(value = {Validators.Add.class}) EduAddressVO vo) {
        return AppResponse.successData(eduAddressIntegration.add(vo));
    }

    @Idempotent(expire="PT2S") //2秒内防重复提交
    @Operation(summary = "地址表修改",description = "地址表修改")
    @PostMapping(value = "/eduaddress0005", produces = "application/json;charset=UTF-8")
    public AppResponse<EduAddressVO> edit(@RequestBody @Validated(value = {Validators.Edit.class}) EduAddressVO vo) {
        return AppResponse.successData(eduAddressIntegration.edit(vo));
    }

    @Idempotent(expire="PT2S") //2秒内防重复提交
    @Operation(summary = "地址表删除",description = "地址表删除")
    @PostMapping(value = "/eduaddress0006", produces = "application/json;charset=UTF-8")
    public AppResponse del(@RequestBody @Validated EduAddressKeyVO vo) {
        eduAddressIntegration.del(vo);
        return AppResponse.successMsg("删除成功！");
    }

    @Operation(summary = "地址管理查询数据(包括父地址名称)",description = "地址管理查询数据(包括父地址名称)")
    @PostMapping(value = "/eduaddress0007", produces = "application/json;charset=UTF-8")
    public AppResponse<PageInfo<EduAddressVO>> getParentAdderssList(@RequestBody @Validated SchoolAddressQueryVO vo) {
        return AppResponse.successData(eduAddressIntegration.getParentAdderssList(vo));
    }

    @Idempotent(expire="PT2S") //2秒内防重复提交
    @Operation(summary = "取消关联学校",description = "取消关联学校")
    @PostMapping(value = "/eduaddress0008", produces = "application/json;charset=UTF-8")
    public AppResponse delAddressSchoolData(@RequestBody @Validated EduAddressVO vo) {
        eduAddressIntegration.delAddressSchoolData(vo);
        return AppResponse.successMsg("删除成功！");
    }

    @Idempotent(expire="PT2S") //2秒内防重复提交
    @Operation(summary = "学校学区数据导出",description = "学校学区数据导出")
    @PostMapping(value = "/eduaddress0009", produces = "application/json;charset=UTF-8")
    @NoSignCrypto
    public void exportSchoolInfo(@RequestBody @Validated SchoolAddressQueryVO vo, HttpServletResponse response) {
        eduAddressIntegration.exportAddressInfo(vo,response);
    }

    @Idempotent(expire="PT2S") //2秒内防重复提交
    @Operation(summary = "设置地址库的行政区划",description = "设置地址库的行政区划")
    @PostMapping(value = "/eduaddress0010", produces = "application/json;charset=UTF-8")
    public AppResponse exportSchoolInfo(@RequestBody  BaseVO vo) {
        eduAddressIntegration.setAreaCode(vo);
        return AppResponse.successMsg("成功");
    }

    @Operation(summary = "修改错误地址状态",description = "修改错误地址状态")
    @PostMapping(value = "/eduaddress0012", produces = "application/json;charset=UTF-8")
    public AppResponse markToNoProcessing(@RequestBody @Validated EduAddressBatchKeyVO vo){
        eduAddressIntegration.markToNoProcessing(vo);
        return AppResponse.successMsg("成功");
    }

    @Operation(summary = "得到账号可以显示的地址信息",description = "得到账号可以显示的地址信息")
    @PostMapping(value = "/eduaddress0013", produces = "application/json;charset=UTF-8")
    public AppResponse<List<EduAreaInfoVO>> getAreaInfo(@RequestBody  BaseVO vo){
        return AppResponse.successData(eduAddressIntegration.getAreaInfo(vo));
    }

    @Operation(summary = "处理错误地址", description = "处理错误地址")
    @PostMapping(value = "/eduaddress0014", produces = "application/json;charset=UTF-8")
    public AppResponse updateErrorAddress(@RequestBody @Validated EduAddressKeysVO vo) {
        if (CollectionUtils.isEmpty(vo.getAddressIds())) {
            return AppResponse.errorMsg("地址id不能为空");
        }
        List<RLock> rLocks = new ArrayList<>();
        for (String addressId : vo.getAddressIds()) {
            RLock lock = redissonClient.getLock(EduCache.EDU_ADDRESS_LOCK + addressId);
            if (lock.tryLock()) {
                rLocks.add(lock);
            } else {
                unLock(rLocks);
                return AppResponse.errorMsg("提交的地址中有正在处理的地址，请稍后再试");
            }
        }
        try {
            eduAddressIntegration.updateErrorAddress(vo);
            return AppResponse.success();
        } finally {
            unLock(rLocks);
        }
    }

    @Operation(summary = "待审核地址统计", description = "待审核地址统计")
    @PostMapping(value = "/eduaddress0015", produces = "application/json;charset=UTF-8")
    public AppResponse<PageInfo<EduAddressStatisticsVO>> toBeReviewedAddressStatistics(@RequestBody @Validated EduAddressQueryVO vo) {
        return AppResponse.successData(eduAddressIntegration.toBeReviewedAddressStatistics(vo));
    }


        private void unLock(List<RLock> rLocks) {
        for (RLock rLock : rLocks) {
            try {
                rLock.unlock();
            } catch (Exception e) {
                log.error("解锁失败,{}", rLock.getName(), e);
            }
        }
    }

}
